from typing import List
import datetime
from datetime import datetime, timedelta
from common.enum.strategy_group_enum import StrategyGroup
from common.enum.strategy_type_enum import StrategyType
from lunarcalendar import LunarDate  # 用于农历日期的转换
from typing import List

from dto.strategy_assessment import RiskAssessment
from dto.strategy_info import StrategyInfoMetadata
from dto.strategy_stock_day import StrategyStockDay
from service.strategy.base_strategy import BaseStrategy


# 获取当前日期对应的农历日期的辅助函数
def get_lunar_date(date: datetime) -> LunarDate:
    return LunarDate.fromSolar(date.year, date.month, date.day)


# 定义法定节假日，不包含年份
def is_holiday(date: datetime) -> bool:
    # 公历节假日
    public_holidays = [
        (1, 1),  # 元旦节
        (5, 1),  # 劳动节
        (10, 1),  # 国庆节
    ]

    # 检查是否是公历节假日
    if (date.month, date.day) in public_holidays:
        return True

    # 检查农历节假日
    lunar_date = get_lunar_date(date)
    lunar_holidays = [
        (1, 1),  # 春节
        (5, 5),  # 端午节
        (8, 15),  # 中秋节
        (4, 4),  # 清明节
    ]

    if (lunar_date.month, lunar_date.day) in lunar_holidays:
        return True

    return False


class HolidayProximityStrategy(BaseStrategy):
    """
    判断当前时间是否在法定节假日的5天内，根据离假期的天数减分
    """

    def analyze(self, trade_info_list: List[StrategyStockDay]) -> RiskAssessment:
        """
        判断当前时间是否在法定节假日的5天内，并根据距离节假日的天数调整分数
        """
        current_date = datetime.now()
        node_point = 0
        description = ""

        # 计算距离最近法定节假日的天数
        for delta in range(6):  # 查找过去和未来6天内的节假日
            check_date = current_date + timedelta(days=delta)
            if is_holiday(check_date):
                node_point = max(0, 5 - delta)  # 离假期越近，分数越低
                description = f"Current date is within {delta} days of a public holiday on {check_date.strftime('%m-%d')}."
                break  # 找到最近的假期后停止检查

        return RiskAssessment(
            stock_code=trade_info_list[0].stock_code if trade_info_list else "Unknown",
            description=description,
            config=self.strategyConfig(),
            node_point=node_point,
        )

    def strategyConfig(self) -> dict:
        """
        返回策略配置
        """
        return StrategyInfoMetadata(
            strategy_code="holiday_proximity",
            strategy_name="节假日前期",
            strategy_group=StrategyGroup.RISK,
            strategy_type=StrategyType.TIME_POINT,
            analysis_day=5,
            strategy_level=1,
        )
